package com.dalxx.util;

import java.util.ArrayList;
import java.util.Iterator;

public class RingBuffer<E> implements Iterable<E>{

	private ArrayList<E> data;
	final int defaultSize=1000;
	private int head=0;
	private int count=0;
	private int capacity;
	public RingBuffer()
	{
		
		this.Alloc(defaultSize);
	}
	public RingBuffer(int size)
	{
		this.Alloc(size);
	}
	
	public void Alloc(int size)
	{
		this.data=new ArrayList<E>(size);
		this.capacity=size;
		
	}
	
	public void Add(E element)
	{
		data.add(head, element);
		head++;
		head%=this.capacity;
		if(count<this.capacity-1)	count++;
		
	}
	
	public void Remove()
	{
		this.count--;
	}
	public int NextIndex(int index)
	{
		index+=this.capacity;
		index%=this.capacity;		
		return index;
	}
	public int FirstIndex()
	{
		return (this.head-this.count+this.capacity)%this.capacity;
	}
	
	public int Size()
	{
		return count;
	}
	public int HeadIndex()
	{
		return this.head;
	}
	public E Get(int index)
	{
		return this.data.get(index%this.capacity);
	}
	
	
	@Override
	public Iterator<E> iterator() {
		return new RingBufferIterator<E>(this);
	}

	public Iterator<E> iterator(int index) {
		return new RingBufferIterator<E>(this, index);
	}

	private class RingBufferIterator<X> implements Iterator<X> {
		
		RingBuffer<X> ringBuffer;
		int i=0;
		
		public RingBufferIterator(RingBuffer<X> e)
		{
			this.ringBuffer=e;
			i=this.ringBuffer.FirstIndex();
			
			
		}
		
		
		public RingBufferIterator(RingBuffer<X> e, int index)
		{
			this.ringBuffer=e;
			this.i=index;
		}
		
		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			
			return (i!=this.ringBuffer.head);
		}
	
		@Override
		public X next() {
			// TODO Auto-generated method stub
			i=this.ringBuffer.NextIndex(i);
			return this.ringBuffer.Get(i);
		}
	
	}
}
